package com.fingard.dsp.bank.directbank.cpcn01;

import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.Base64Helper;
import com.fingard.text.StringHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

/**
 * 中金支付批量代收付接口
 */
public class CPCN01BatPayRec extends CPCN01Base implements IBatPayRec {

	@Override
	public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
		if ("198802".equals(p_req1988.reqHeader.commandCode)) {
			return d_198802_BatPay(p_req1988);
		} else {
			return d_198801_BatPay(p_req1988);
		}
	}

	public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
		if ("918802".equals(p_req9188.reqHeader.commandCode)) {
			return d_918802_BatPay(p_req9188);
		} else {
			return d_918801_BatPay(p_req9188);
		}
	}

	/**
	 * 参考文档：中金支付 报文交换技术规范 第2部分 批量代付 V1.0.1.pdf
	 * 章节：1510-批量代付
	 */
    private RetAtsBatPayRec d_198802_BatPay(ReqBatPayRec p_req1988) {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1988.ownAct, "");
            if(actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)){
                retAts.respCode = "0";
                if(actItem == null){
                    retAts.respInfo = "未找到账号"+p_req1988.ownAct+"的批量商户配置节点";
                }else{
                    retAts.respInfo = "账号"+p_req1988.ownAct+"的证书文件不存在";
                }
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9981;
                retAts.writeRetToATS();
                return retAts;
            }

            CPCN01Header bankHeader = new CPCN01Header();
            bankHeader.transCode = "1510";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeElementString("TxCode", bankHeader.transCode);
            xmlWriter.writeEndElement();
            xmlWriter.writeStartElement("Body");
            xmlWriter.writeElementString("InstitutionID", actItem.merchantId);
            xmlWriter.writeElementString("BatchNo", p_req1988.reqBatchNO);
            xmlWriter.writeElementString("TotalAmount", StringHelper.amountMultiply100(p_req1988.totalAmt));
            xmlWriter.writeElementString("TotalCount", p_req1988.totalNum);
            xmlWriter.writeElementString("Remark", p_req1988.useType);
            String paymentFlag = getBankConfig().getValueAsString("paymentFlag");
            if (StringHelper.hasAnyChar(paymentFlag)) {
                xmlWriter.writeElementString("PaymentFlag", p_req1988.totalNum);
                if ("1".equals(paymentFlag) || "2".equals(paymentFlag) || "3".equals(paymentFlag)) {
                    xmlWriter.writeStartElement("Payer");// 付款人
                    xmlWriter.writeElementString("PaymentAccountName", p_req1988.ownActName);
                    xmlWriter.writeElementString("PaymentAccountNumber", p_req1988.ownAct);
            		xmlWriter.writeEndElement();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "请求报文中paymentFlag节点为空，请检查CPCN01/config.xml中'paymentFlag'节点配置";
                return retAts;
            }

            while(p_req1988.readRecord()) {
				xmlWriter.writeStartElement("Item");
                xmlWriter.writeElementString("ItemNo", p_req1988.readedDetail.askNumber);
                xmlWriter.writeElementString("Amount", StringHelper.amountDivide100(p_req1988.readedDetail.payAmount));
                xmlWriter.writeElementString("BankID", getBankConfig().getMapValueByKey("bankMapping", p_req1988.readedDetail.payBankCode));// 银行数字编码
                if (p_req1988.readedDetail.isPrivate.equals("1")) {
                    xmlWriter.writeElementString("AccountType", "11");//个人账户
                }else {
                    xmlWriter.writeElementString("AccountType", "12");//企业账户
                }

                xmlWriter.writeElementString("AccountName", p_req1988.readedDetail.payName);
                xmlWriter.writeElementString("AccountNumber", p_req1988.readedDetail.payAct);
                xmlWriter.writeElementString("BankNoByPBC", p_req1988.readedDetail.cnapsCode);
                xmlWriter.writeElementString("BranchName", p_req1988.readedDetail.payBankLocation);
				xmlWriter.writeElementString("Province", p_req1988.readedDetail.getOppProvinceAndCity()[0]);
				xmlWriter.writeElementString("City", p_req1988.readedDetail.getOppProvinceAndCity()[1]);
                xmlWriter.writeElementString("Note", p_req1988.readedDetail.memo);
				xmlWriter.writeElementString("PhoneNumber", p_req1988.readedDetail.cellPhone);
                xmlWriter.writeEndElement();
            }
            xmlWriter.writeEndDocument();

            // 请求报文
            WriteBankLogStep2(xmlWriter.toXmlString());

            // 发送银行
            String[] tmpStrRet = sendToBank("sync",xmlWriter.toXmlString(),actItem);

            // 解析银行返回
            if(tmpStrRet[0].length() == 0){
                String[] respInfo = tmpStrRet[1].split(",");
                String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());

                WriteBankLogStep3(respXml);

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);

                if(tmpBkReader != null){
                    retAts.respCode = "0";
                    retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
                    retAts.reqSeqID = p_req1988.reqBatchNO;
					retAts.transState = PaymentState.PAYING;
					retAts.payInfoCode = "I4001";
                }else{
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            }else if(tmpStrRet[0].equals(ConnState.FAIL)){
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.reqSeqID = p_req1988.reqBatchNO;
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = tmpStrRet[0];
            }else{
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        }catch (Exception e) {
            retAts.respCode = "-1";
            retAts.respInfo = e.toString();
            e.printStackTrace();
        }

        if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
            retAts.reqSeqID = p_req1988.reqBatchNO;
        }

        retAts.writeRetToATS();
        return retAts;
    }

    /**
	 * 批量代付提交
	 *        -- 分实时和非实时
	 */
	public RetAtsBatPayRec d_198801_BatPay(ReqBatPayRec p_req1988)	throws Exception {
		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req1988.reqHeader);
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1988.ownAct, "");
			if(actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)){
				retAts.respCode = "0";
				if(actItem == null){
					retAts.respInfo = "未找到账号"+p_req1988.ownAct+"的批量商户配置节点";
				}else{
					retAts.respInfo = "账号"+p_req1988.ownAct+"的证书文件不存在";
				}
				retAts.reqSeqID = p_req1988.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = FailCode.E9981;
				retAts.writeRetToATS();
				return retAts;
			}
			
			CPCN01Header bankHeader = new CPCN01Header();
			
			if (p_req1988.reqHeader.commandCode.equals("198801")) {
				bankHeader.transCode = "4534";
			}else {
				bankHeader.transCode = "4536";
			}
			
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader);
			
			xmlWriter.writeElementString("TxCode", bankHeader.transCode);
			xmlWriter.writeElementString("InstitutionID", actItem.merchantId);
			xmlWriter.writeEndElement();
			xmlWriter.writeStartElement("Body");
			xmlWriter.writeElementString("BatchNo", p_req1988.reqBatchNO);
			xmlWriter.writeElementString("TotalAmount", StringHelper.amountMultiply100(p_req1988.totalAmt));
			xmlWriter.writeElementString("TotalCount", p_req1988.totalNum);
			xmlWriter.writeElementString("Remark", p_req1988.useType);
			xmlWriter.writeStartElement("Payer");// 付款人
			xmlWriter.writeElementString("PaymentAccountName", p_req1988.ownActName);
			xmlWriter.writeElementString("PaymentAccountNumber", p_req1988.ownAct);
			xmlWriter.writeEndElement();
			while(p_req1988.readRecord()) {
				xmlWriter.writeStartElement("Payee");
				xmlWriter.writeElementString("ItemNo", p_req1988.readedDetail.askNumber);
				xmlWriter.writeElementString("Amount", StringHelper.amountDivide100(p_req1988.readedDetail.payAmount));
				xmlWriter.writeElementString("BankID", getBankConfig().getMapValueByKey("bankMapping", p_req1988.readedDetail.payBankCode));// 银行数字编码
				if (p_req1988.readedDetail.isPrivate.equals("1")) {
					xmlWriter.writeElementString("AccountType", "11");//个人账户
				}else {
					xmlWriter.writeElementString("AccountType", "12");//企业账户
				}
				
				xmlWriter.writeElementString("BankAccountName", p_req1988.readedDetail.recName);
				xmlWriter.writeElementString("BankAccountNumber", p_req1988.readedDetail.recAct);
				xmlWriter.writeElementString("PhoneNumber", p_req1988.readedDetail.cellPhone);
				xmlWriter.writeElementString("Note", p_req1988.readedDetail.memo);
				xmlWriter.writeEndElement();
			}
			
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			// 请求报文
			WriteBankLogStep2(xmlWriter.toXmlString());	
						
			// 发送银行
			String[] tmpStrRet = sendToBank("sync",xmlWriter.toXmlString(),actItem);
			
			// 解析银行返回
			if(tmpStrRet[0].length() == 0){
				String[] respInfo = tmpStrRet[1].split(",");
				String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());
				
				WriteBankLogLn("银行返回的报文为：" + respXml);
				
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				
				if(tmpBkReader != null){
					retAts.respCode = "0";
					retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
					retAts.reqSeqID = p_req1988.reqBatchNO;
					retAts.transState = "";
					retAts.payInfoCode = retAts.transState;
				}else{
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else if(tmpStrRet[0].equals(ConnState.FAIL)){
				retAts.respCode = "0";
				retAts.respInfo = tmpStrRet[1];
				retAts.reqSeqID = p_req1988.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = tmpStrRet[0];
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.toString();
			e.printStackTrace();
		}
		
		if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
			retAts.reqSeqID = p_req1988.reqBatchNO;
		}
		
		retAts.writeRetToATS();
		return retAts;
	}

	/**
	 * 批量代付状态查询
	 */
	public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998)	throws Exception {
		RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req1998.reqHeader);
		retAts.respCode = "";
		
		try{
			ActSetItem actItem = getBankConfig().getActSetItem(p_req1998.ownAct, "");
			if (actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath)|| !FileHelper.existFile(actItem.oppCertFilePath)) {
				if (actItem == null) {
					throw new Exception("未找到账号" + p_req1998.ownAct + "对应的商户配置节点");
				} else {
					throw new Exception("账号" + p_req1998.ownAct + "对应的证书文件不存在");
				}
			}

			CPCN01Header bankHeader = new CPCN01Header();
			XmlTextWriter xmlWriter = new XmlTextWriter();

			if ("198802".equals(p_req1998.reqHeader.commandCode)) {
				bankHeader.transCode = "1520";
				writeCommonHeader(xmlWriter, bankHeader);
				xmlWriter.writeElementString("TxCode",bankHeader.transCode);
				xmlWriter.writeEndElement();
				xmlWriter.writeStartElement("Body");
				xmlWriter.writeElementString("InstitutionID",actItem.merchantId);
				xmlWriter.writeElementString("BatchNo",p_req1998.reqBatchNO);
			} else {
				bankHeader.transCode = "4538";
				writeCommonHeader(xmlWriter, bankHeader);
				xmlWriter.writeElementString("TxCode",bankHeader.transCode);
				xmlWriter.writeElementString("InstitutionID",actItem.merchantId);
				xmlWriter.writeEndElement();
				xmlWriter.writeStartElement("Body");
				xmlWriter.writeElementString("BatchNo",p_req1998.reqBatchNO);
				if (p_req1998.reqHeader.commandCode.equals("198801")) {
					xmlWriter.writeElementString("TxType","4534");
				}else {
					xmlWriter.writeElementString("TxType","4534");
				}
			}

			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			// 请求报文
			WriteBankLogStep2(xmlWriter.toXmlString());	 
			
			// 发送银行
			String[] tmpStrRet = sendToBank("sync", xmlWriter.toXmlString(), actItem);
						
		
			if(tmpStrRet[0].length() == 0){
				String[] respInfo = tmpStrRet[1].split(",");
				String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());
				
				WriteBankLogStep3(respXml);
				
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				
				if(tmpBkReader != null) {
					String tmpRetCode = tmpBkReader.getFirstText("/Response/Head/Code");
					String tmpRetMsg = tmpBkReader.getFirstText("/Response/Head/Message");
					
	                if ("2000".equals(tmpRetCode)){
						retAts.respCode = "0";
						retAts.respInfo = tmpRetMsg;
						retAts.reqSeqID = tmpBkReader.getFirstText("/Response/Body/BatchNo");
						retAts.writeBeforeDetail();

						while(tmpBkReader.read("/Response/Body/Payee")){
							RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

							retAts.transState = tmpBkReader.readedXElement.getSingleText("ResponseCode");
							tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("ItemNo");
							tmpRetDetail.recAct = tmpBkReader.readedXElement.getSingleText("BankAccountNumber");
							tmpRetDetail.recName = tmpBkReader.readedXElement.getSingleText("BankAccountName");
							tmpRetDetail.payAmount = tmpBkReader.readedXElement.getSingleText("Amount");
							tmpRetDetail.result = tmpBkReader.readedXElement.getSingleText("Status");
							tmpRetDetail.payInfoCode = tmpRetDetail.result + "+" + retAts.transState;
							tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("ResponseMessage");
							retAts.writeRetDetail(tmpRetDetail);
						}
                    } else if("250001".equals(tmpRetCode)){
                        retAts.respCode = "0";
                        retAts.reqSeqID = p_req1998.reqBatchNO;
                        retAts.transState = tmpRetCode ;
                        retAts.payInfoCode = tmpRetCode;
                        retAts.writeAfterDetail();
                        return retAts;
                    }else{
						retAts.respCode = "-1";
						retAts.respInfo = tmpRetMsg;
					}
	                
				}else{
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.getMessage();
			e.printStackTrace();
		}
		
		if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
			retAts.reqSeqID = p_req1998.reqBatchNO;
		}
		
		if(retAts.respCode.equals("-1")){
			retAts.writeBeforeDetail();
		}
		
		retAts.writeAfterDetail();
		return retAts;
	}

	/**
	 * 批量代扣提交
	 */
	public RetAtsBatPayRec d_918801_BatPay(ReqBatPayRec p_req9188) throws Exception {
		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);
		
		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9188.ownAct, "");
			if(actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)){
				retAts.respCode = "0";
				if(actItem == null){
					retAts.respInfo = "未找到账号"+p_req9188.ownAct+"的批量商户配置节点";
				}else{
					retAts.respInfo = "账号"+p_req9188.ownAct+"的证书文件不存在";
				}
				retAts.reqSeqID = p_req9188.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = FailCode.E9981;
				retAts.writeRetToATS();
				return retAts;
			}
			
			CPCN01Header bankHeader = new CPCN01Header();
			bankHeader.transCode = "1610";
			
			// 拼请求报文
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader);
			xmlWriter.writeElementString("TxCode", bankHeader.transCode);
			xmlWriter.writeEndElement();
			xmlWriter.writeStartElement("Body");
			xmlWriter.writeElementString("InstitutionID", actItem.merchantId);//机构编号
			xmlWriter.writeElementString("BatchNo", p_req9188.reqBatchNO);
			xmlWriter.writeElementString("TotalAmount", StringHelper.amountMultiply100(p_req9188.totalAmt));
			xmlWriter.writeElementString("TotalCount", p_req9188.totalNum);
			xmlWriter.writeElementString("Remark", p_req9188.useType);// 备注
			
			while(p_req9188.readRecord()) {
				xmlWriter.writeStartElement("Item");
				xmlWriter.writeElementString("ItemNo", p_req9188.readedDetail.askNumber);
				xmlWriter.writeElementString("Amount", StringHelper.amountMultiply100(p_req9188.readedDetail.payAmount));
				xmlWriter.writeElementString("BankID", getBankConfig().getMapValueByKey("bankMapping", p_req9188.readedDetail.payBankCode));
				if (p_req9188.readedDetail.isPrivate.equals("1")) {
					xmlWriter.writeElementString("AccountType", "11");
//					xmlWriter.writeElementString("CardMediaType", "借记卡");
				}else {
					xmlWriter.writeElementString("AccountType", "12");
//					xmlWriter.writeElementString("CardMediaType", "");
				}
				
				xmlWriter.writeElementString("AccountName", p_req9188.readedDetail.payName);
				xmlWriter.writeElementString("AccountNumber", p_req9188.readedDetail.payAct);
				xmlWriter.writeElementString("BranchName", p_req9188.readedDetail.payBankLocation);
				xmlWriter.writeElementString("Note", p_req9188.readedDetail.memo);
				xmlWriter.writeElementString("ContractNo", p_req9188.readedDetail.authCode);
				xmlWriter.writeElementString("ContractUserID", p_req9188.readedDetail.authAgNum);
				xmlWriter.writeElementString("PhoneNumber", p_req9188.readedDetail.cellPhone);
				xmlWriter.writeElementString("IdentificationType", convertCertTypeToBank(p_req9188.readedDetail.certType));
				xmlWriter.writeElementString("IdentificationNumber", p_req9188.readedDetail.certNum);
				xmlWriter.writeElementString("SettlementFlag", "0001");
				
				if (p_req9188.readedDetail.isPrivate.equals("1")) {
//					xmlWriter.writeElementString("CardMediaType", "10");// 不上送，默认为借记卡
				}else {
					xmlWriter.writeElementString("CardMediaType", "");
				}
				
				xmlWriter.writeEndElement();
			}
			
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();
			
			//发送银行
			String[] tmpStrRet = sendToBank("sync",xmlWriter.toXmlString(),actItem);
			
			
			//解析银行返回
			if(tmpStrRet[0].length() == 0){
				String[] respInfo = tmpStrRet[1].split(",");
				String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());
				
				WriteBankLogLn("银行返回的报文为：" + respXml);
				
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				
				if (tmpBkReader != null) {
					String tmpRespCode = tmpBkReader.getFirstText("/Response/Head/Code");
					
					if (tmpRespCode.equals("2000")) {
						retAts.respCode = "0";
						retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
						retAts.reqSeqID = p_req9188.reqBatchNO;
						retAts.transState = "";
						retAts.payInfoCode = retAts.transState;
					}else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
						retAts.transState = PaymentState.FAIL_Batch;
						retAts.payInfoCode = tmpRespCode;
					}
				}else {
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else if(tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)){
				retAts.respCode = "0";
				retAts.respInfo = tmpStrRet[1];
				retAts.reqSeqID = p_req9188.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = tmpStrRet[1];
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.toString();
			e.printStackTrace();
		}
		
		if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
			retAts.reqSeqID = p_req9188.reqBatchNO;
		}
		retAts.writeRetToATS();
		return retAts;
	}

	/**
	 * 参考文档：中金支付 报文交换技术规范 第2部分 批量代收 V1.0.0.pdf
	 * 章节：1610-批量代收
	 */
	public RetAtsBatPayRec d_918802_BatPay(ReqBatPayRec p_req9188) throws Exception {
		RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_req9188.reqHeader);

		try {
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9188.ownAct, "");
			if(actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)){
				retAts.respCode = "0";
				if(actItem == null){
					retAts.respInfo = "未找到账号"+p_req9188.ownAct+"的批量商户配置节点";
				}else{
					retAts.respInfo = "账号"+p_req9188.ownAct+"的证书文件不存在";
				}
				retAts.reqSeqID = p_req9188.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = FailCode.E9981;
				retAts.writeRetToATS();
				return retAts;
			}

			CPCN01Header bankHeader = new CPCN01Header();
			bankHeader.transCode = "1610";

			// 拼请求报文
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader);
			xmlWriter.writeElementString("TxCode", bankHeader.transCode);
			xmlWriter.writeEndElement();
			xmlWriter.writeStartElement("Body");
			xmlWriter.writeElementString("InstitutionID", actItem.merchantId);//机构编号
			xmlWriter.writeElementString("BatchNo", p_req9188.reqBatchNO);
			xmlWriter.writeElementString("TotalAmount", StringHelper.amountMultiply100(p_req9188.totalAmt));
			xmlWriter.writeElementString("TotalCount", p_req9188.totalNum);
			xmlWriter.writeElementString("Remark", p_req9188.useType);// 备注

			while(p_req9188.readRecord()) {
				xmlWriter.writeStartElement("Item");
				xmlWriter.writeElementString("ItemNo", p_req9188.readedDetail.askNumber);
				xmlWriter.writeElementString("Amount", StringHelper.amountMultiply100(p_req9188.readedDetail.payAmount));
				xmlWriter.writeElementString("BankID", getBankConfig().getMapValueByKey("bankMapping", p_req9188.readedDetail.payBankCode));
				if (p_req9188.readedDetail.isPrivate.equals("1")) {
					xmlWriter.writeElementString("AccountType", "11");
//					xmlWriter.writeElementString("CardMediaType", "借记卡");
				}else {
					xmlWriter.writeElementString("AccountType", "12");
//					xmlWriter.writeElementString("CardMediaType", "");
				}
				xmlWriter.writeElementString("AccountName", p_req9188.readedDetail.payName);
				xmlWriter.writeElementString("AccountNumber", p_req9188.readedDetail.payAct);
				xmlWriter.writeElementString("BranchName", p_req9188.readedDetail.payBankLocation);
				xmlWriter.writeElementString("Province", p_req9188.readedDetail.getOppProvinceAndCity()[0]);
				xmlWriter.writeElementString("City", p_req9188.readedDetail.getOppProvinceAndCity()[1]);
				xmlWriter.writeElementString("Note", p_req9188.readedDetail.memo);
				xmlWriter.writeElementString("ContractNo", p_req9188.readedDetail.authCode);
				xmlWriter.writeElementString("ContractUserID", p_req9188.readedDetail.authAgNum);
				xmlWriter.writeElementString("PhoneNumber", p_req9188.readedDetail.cellPhone);
				String certNum = p_req9188.readedDetail.certNum;
				String certType = convertCertTypeToBank(p_req9188.readedDetail.certType);
				if (StringHelper.hasAnyChar(certNum)) {
					xmlWriter.writeElementString("IdentificationNumber", certNum);
					xmlWriter.writeElementString("IdentificationType", certType);
				} else {
					xmlWriter.writeElementString("IdentificationNumber", "");
					xmlWriter.writeElementString("IdentificationType", "");
				}
				xmlWriter.writeElementString("SplitType", "10");
				xmlWriter.writeElementString("SettlementFlag", "0001");

				if (p_req9188.readedDetail.isPrivate.equals("1")) {
//					xmlWriter.writeElementString("CardMediaType", "10");// 不上送，默认为借记卡
				}else {
					xmlWriter.writeElementString("CardMediaType", "");
				}
				xmlWriter.writeElementString("BankNoByPBC", p_req9188.readedDetail.cnapsCode);
				xmlWriter.writeEndElement();
			}

			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();

			WriteBankLogStep2(xmlWriter.toXmlString());
			//发送银行
			String[] tmpStrRet = sendToBank("sync",xmlWriter.toXmlString(),actItem);

			//解析银行返回
			if(tmpStrRet[0].length() == 0){
				String[] respInfo = tmpStrRet[1].split(",");
				String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());

				WriteBankLogStep3(respXml);

				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);

				if (tmpBkReader != null) {
					String tmpRespCode = tmpBkReader.getFirstText("/Response/Head/Code");

					if (tmpRespCode.equals("2000")) {
						retAts.respCode = "0";
						retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
						retAts.reqSeqID = p_req9188.reqBatchNO;
                        retAts.transState = PaymentState.PAYING;
						retAts.payInfoCode = "I4001";
					}else {
						retAts.respCode = "-1";
						retAts.respInfo = tmpBkReader.getFirstText("/Response/Head/Message");
						retAts.transState = PaymentState.FAIL_Batch;
						retAts.payInfoCode = tmpRespCode;
					}
				}else {
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else if(tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)){
				retAts.respCode = "0";
				retAts.respInfo = tmpStrRet[1];
				retAts.reqSeqID = p_req9188.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = tmpStrRet[1];
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.toString();
			e.printStackTrace();
		}

		if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
			retAts.reqSeqID = p_req9188.reqBatchNO;
		}
		retAts.writeRetToATS();
		return retAts;
	}

	/**
	 * 批量代扣状态查询
	 */
	public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198)	throws Exception {
		RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_req9198.reqHeader);
		retAts.respCode = "";
		
		try{
			ActSetItem actItem = getBankConfig().getActSetItem(p_req9198.ownAct, "");
			if(actItem == null || !FileHelper.existFile(actItem.ownKeyStorePath) || !FileHelper.existFile(actItem.oppCertFilePath)){
				retAts.respCode = "0";
				if(actItem == null){
					retAts.respInfo = "未找到账号"+p_req9198.ownAct+"的批量商户配置节点";
				}else{
					retAts.respInfo = "账号"+p_req9198.ownAct+"的证书文件不存在";
				}
				retAts.reqSeqID = p_req9198.reqBatchNO;
				retAts.transState = PaymentState.FAIL_Batch;
				retAts.payInfoCode = FailCode.E9981;
				return retAts;
			}
		
			CPCN01Header bankHeader = new CPCN01Header();
			bankHeader.transCode = "1620";
			
			// 拼请求报文
			XmlTextWriter xmlWriter = new XmlTextWriter();
			writeCommonHeader(xmlWriter, bankHeader);
			xmlWriter.writeElementString("TxCode", bankHeader.transCode);
			xmlWriter.writeEndElement();
			xmlWriter.writeStartElement("Body");
			xmlWriter.writeElementString("InstitutionID", actItem.merchantId);//机构编号
			xmlWriter.writeElementString("BatchNo", p_req9198.reqBatchNO);
			xmlWriter.writeEndElement();
			xmlWriter.writeEndDocument();

			WriteBankLogStep2(xmlWriter.toXmlString());
			String[] tmpStrRet = sendToBank("sync", xmlWriter.toXmlString(),actItem);
			
			// 解析银行返回
			if(tmpStrRet[0].length() == 0){
				String[] respInfo = tmpStrRet[1].split(",");
				String respXml = Base64Helper.getFromBase64(respInfo[0], getCharset());

				WriteBankLogStep3(respXml);
				
				StringBuilder tmpSbMsg = new StringBuilder();
				XmlTextReader tmpBkReader = loadBankRespXmlReader(respXml, tmpSbMsg);
				
				if(tmpBkReader != null){
					String tmpRetCode = tmpBkReader.getFirstText("/Response/Head/Code");
					String tmpRetMsg = tmpBkReader.getFirstText("/Response/Head/Message");
					
	                if ("2000".equals(tmpRetCode)){
						retAts.respCode = "0";
						retAts.respInfo = tmpRetMsg;
						retAts.reqSeqID = tmpBkReader.getFirstText("/Response/Body/BatchNo");
						retAts.writeBeforeDetail();

						while(tmpBkReader.read("/Response/Body/Item")){
							RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();

							retAts.transState = tmpBkReader.readedXElement.getSingleText("ResponseCode");
							tmpRetDetail.payAct = tmpBkReader.readedXElement.getSingleText("AccountNumber");
							tmpRetDetail.payName = tmpBkReader.readedXElement.getSingleText("AccountName");
							tmpRetDetail.payAmount = tmpBkReader.readedXElement.getSingleText("Amount");
							tmpRetDetail.postScript = tmpBkReader.readedXElement.getSingleText("ItemNo");
							tmpRetDetail.result = tmpBkReader.readedXElement.getSingleText("Status");
							tmpRetDetail.payInfoCode = tmpRetDetail.result + "+" + retAts.transState;
                            tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("ResponseMessage");
							retAts.writeRetDetail(tmpRetDetail);
						}
					}else if("250001".equals(tmpRetCode)){
						retAts.respCode = "0";
						retAts.reqSeqID = p_req9198.reqBatchNO;
						retAts.transState = tmpRetCode ;
						retAts.payInfoCode = tmpRetCode;
						retAts.writeAfterDetail();
						return retAts;
					}else{
						retAts.respCode = "-1";
						retAts.respInfo = tmpRetMsg;
					}
				}else{
					retAts.respCode = "-1";
					retAts.respInfo = tmpSbMsg.toString();
				}
			}else{
				retAts.respCode = "-1";
				retAts.respInfo = tmpStrRet[1];
			}
		}catch (Exception e) {
			retAts.respCode = "-1";
			retAts.respInfo = e.getMessage();
			e.printStackTrace();
		}
		
		if(retAts.respCode.equals("-1") && StringHelper.isNullOrEmpty(retAts.reqSeqID)){
			retAts.reqSeqID = p_req9198.reqBatchNO;
		}
		
		if(retAts.respCode.equals("-1")){
			retAts.writeBeforeDetail();
		}

		retAts.writeAfterDetail();
		return retAts;
	}
}
